from tensorflow.keras.application.vgg16 import VGG16,preprocess_input
from tensorflow.keras.preprocessing import image
import numpy as np
import time 
from joblib import dump,load
import yaml 
import os
import sys
# 获取 0_setting.yaml 中的键 key 对应的值 value
def get(key):
    with open("0_setting.yaml","r",encoding='utf-8') as f:
        config=yaml.safe_load(f)
    value=config[key]
    return value

# 预处理图像, 把图像设置为指定大小之后，展平返回
def preprocess_image(file_name, new_size=(224,224)):
    # 1. 读取图像 vgg16输入的值被限制在(224,224)
    img=iamge.load(file_name,target_size=new_size)

    #2.转为numpy数组
    img=iamge.to_array(img)

    #3. 把单幅图像放到一个数组中，虽然只有一幅图像，但是我们仍然需要扩展数组的维度，以适应VGG16模型的输入尺寸要求（模型要求输入为4D张量）
    img=np.array([img])

    #4. 使用VGG16模型的预处理函数对图像进行预处理，该步骤包括颜色空间的转换、缩放等
    X = preprocess_input(img)

    # 5. # 加载预训练的VGG16模型，不包括顶部的全连接层（include_top=False），因为我们的目标是提取特征，而不是进行分类
    # weights='imagenet' 表示使用在 ImageNet 数据集上预训练的权重，这些权重可以帮助我们更好地提取特征
    # pooling="max" 表示使用最大池化来池化特征图，这可以帮助我们更好地保留特征信息，并且对结果进行大幅度降维
    model = VGG16(weights='imagenet', include_top=False,pooling="max")

    # 6. 使用 VGG16 模型对图像进行特征提取，model.predict(X) 返回一个包含特征向量的数组
    # [0] 表示我们只提取第一张图像的特征向量，因为我们只输入了一张图像
    y = model.predict(X)[0]
    #print(img.shape)
    return y

# 用joblib把叫做 name 的对象 obj 保存(序列化)到位置 loc
def dump1(obj, name, loc):
    start = time.time()
    print(f"把{name}保存到{loc}") 
    # 此处序列化对象
    dump(obj,loc)
    end = time.time()
    print(f"保存完毕,文件位置:{loc}, 大小:{os.path.getsize(loc) / 1024 / 1024:.3f}M")
    print(f"运行时间:{end - start:.3f}秒")

# 用joblib读取(反序列化)位置loc的对象obj,对象名为name
def load1(name, loc):
    print(f"从{loc}提取文件{name}")
    # 此处反序列化对象
    obj=load(loc)
    return obj



